package com.lvtu.monitor.shiro.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Repository;

import com.lvtu.monitor.shiro.dao.CacheHelper;
import com.lvtu.monitor.shiro.dao.CacheHelper.CacheType;
import com.lvtu.monitor.shiro.dao.UserDao;
import com.lvtu.monitor.shiro.entity.User;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-1-28
 * <p>Version: 1.0
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public User createUser(final User user) {
        final String sql = "insert into sys_user(username, password, salt, role_ids, locked) values(?,?,?,?,?)";
        //System.out.println("[SQL:]" + sql);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement psst = connection.prepareStatement(sql, new String[]{"id"});
                int count = 1;
                psst.setString(count++, user.getUsername());
                psst.setString(count++, user.getPassword());
                psst.setString(count++, user.getSalt());
                psst.setString(count++, user.getRoleIdsStr());
                psst.setBoolean(count++, user.getLocked());
                return psst;
            }
        }, keyHolder);

        user.setId(keyHolder.getKey().longValue());
        return user;
    }

    public User updateUser(User user) {
        String sql = "update sys_user set username=?, password=?, salt=?, role_ids=?, locked=? where id=?";
        //System.out.println("[SQL:]" + sql);
        jdbcTemplate.update(
                sql, user.getUsername(), user.getPassword(), user.getSalt(), user.getRoleIdsStr(), user.getLocked(), user.getId());
        CacheHelper.cleanCache(CacheType.user, user.getId());
        CacheHelper.cleanCache(CacheType.user, user.getUsername());
        return user;
    }

    public void deleteUser(Long userId) {
        String sql = "delete from sys_user where id=?";
        //System.out.println("[SQL:]" + sql);
        CacheHelper.cleanCache(CacheType.user, userId);
        jdbcTemplate.update(sql, userId);
    }

    @Override
    public User findOne(Long userId) {
    	Object cachedObj = CacheHelper.getCache(CacheType.user, userId);
    	if (cachedObj != null) {
    		return (User)cachedObj;
    	}
    	
        String sql = "select id, username, password, salt, role_ids as roleIdsStr, locked from sys_user where id=?";
        //System.out.println("[SQL:]" + sql);
        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class), userId);
        if(userList.size() == 0) {
            return null;
        }
        User user = userList.get(0);
        CacheHelper.setCache(CacheType.user, userId, user);
        return user;
    }

    @Override
    public List<User> findAll() {
        String sql = "select id, username, password, salt, role_ids as roleIdsStr, locked from sys_user";
        //System.out.println("[SQL:]" + sql);
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class));
    }


    @Override
    public User findByUsername(String username) {
    	Object cachedObj = CacheHelper.getCache(CacheType.user, username);
    	if (cachedObj != null) {
    		return (User)cachedObj;
    	}
    	
        String sql = "select id, username, password, salt, role_ids as roleIdsStr, locked from sys_user where username=?";
        //System.out.println("[SQL:]" + sql);
        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class), username);
        if(userList.size() == 0) {
            return null;
        }
        User user = userList.get(0);
        CacheHelper.setCache(CacheType.user, username, user);
        return user;
    }
}
